package org.hamster.common.utils
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.display.GradientType;
	import flash.display.Shape;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import mx.controls.Image;
	
	/**
	 * @author jack yin grossopforever@gmail.com
	 */
	 	
	public class ImageUtil
	{
		/**
		 * if transparent is true, then the background color of 
		 * the displayObject is transparent.
		 */
		public static function toImage(displayObject:DisplayObject, 
				transparent:Boolean = false):Image
		{
			var bd:BitmapData;
			if (transparent) {
				bd = new BitmapData(
					displayObject.width, displayObject.height, true, 0x00);
			} else {
				bd = new BitmapData(displayObject.width, displayObject.height);
			}
			bd.draw(displayObject);
			var bm:Bitmap = new Bitmap(bd);
			var im:Image = new Image();
			im.width = displayObject.width;
			im.height = displayObject.height;
			im.source = bm;
			return im;
		}
		
		public static function toBitmapData(displayObject:DisplayObject):BitmapData
		{
			var bd:BitmapData;
				bd = new BitmapData(
					displayObject.width, displayObject.height, true, 0x00);
			bd.draw(displayObject);
			return bd;
		}

		
		public static function splitImage(
				image:Image, rect:Rectangle, destPoint:Point):Image
		{
			var result:Image = new Image();
			var bd:BitmapData = new BitmapData(rect.width, rect.height);
			bd.copyPixels(image.source.bitmapData, rect, destPoint);
			result.width = rect.width;
			result.height = rect.height;
			result.source = new Bitmap(bd);
			return result;
		}
		
		// TODO: bitmapData support
		public static function fadeImage(target:DisplayObject, targetMatrix:Matrix = null,
			pi:Number = 0, alphas:Array = null, ratios:Array = null):Image
		{
			if(alphas == null || alphas.length == 0) alphas = [0, 1];
			if(ratios == null || ratios.length == 0) ratios = [0, 255];
			var colors:Array = new Array(alphas.length);
			for (var i:int = 0; i < colors.length; i++) {
				colors[i] = 0;
			}
			
			var bd:BitmapData = new BitmapData(target.width, target.height);
			bd.draw(target);
			var temp:BitmapData = new BitmapData(target.width, target.height);
			temp.draw(bd, targetMatrix);
			var shape:Shape = new Shape();
			var gradientMatrix:Matrix = new Matrix();
			gradientMatrix.createGradientBox(target.width, target.height, pi); 
			shape.graphics.beginGradientFill(GradientType.LINEAR, colors,
					alphas, ratios, gradientMatrix);
			shape.graphics.drawRect(0, 0, target.width, target.height);
			shape.graphics.endFill();
			temp.draw(shape, null, null, BlendMode.ALPHA);
			
			var result:Image = new Image();
			result.source = new Bitmap(temp);
			return result;
		}
		
		public static function toReflactor(source:DisplayObject, fromAlpha:Number = 0.5, toAlpha:Number = 0.5, gradient:Boolean = true):BitmapData {
			var bd:BitmapData = new BitmapData(source.width, source.height, true, 0x00000000);
			bd.lock();
			var mtx:Matrix = new Matrix();
			mtx.d = -1;
			mtx.ty = bd.height;
			bd.draw(source, mtx, new ColorTransform(1,1,1,0.5));
//			if (gradient) {
//				var width:int = bd.width;
//				var height:int = bd.height;
//				mtx = new Matrix();
//				mtx.createGradientBox(width, height, 0.5 * Math.PI);
//				var shape:Shape = new Shape();
//				shape.graphics.beginGradientFill(GradientType.LINEAR, [0, 0], [fromAlpha, toAlpha], [0, 0xFF], mtx);
//				shape.graphics.drawRect(0, 0, width, height);
//				shape.graphics.endFill();
//				var mask_bd:BitmapData = new BitmapData(width, height, true, 0);
//				mask_bd.draw(shape);
//				bd.copyPixels(bd, bd.rect, new Point(0, 0), mask_bd, new Point(0, 0), false);
//			}
//			
			bd.unlock();
			return bd;
//			var ref:Bitmap = new Bitmap();
//			ref.y = source.height + source.y;
//			ref.x = source.x;
//			ref.bitmapData = bd;
//			picSource.parent.addChild(ref);

		}
			
	}
}